package git.common;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class DatabaseUtils
{
	public static int copyTable(Connection srcConn, String srcTab
			, Connection destConn, String destTab, int buffSize)
		throws Exception
	{
		//List srcColList = getTableColumns(srcConn, srcTab);
		List destColList = getTableColumns(destConn, destTab);
		
		StringBuffer srcBuff = new StringBuffer("SELECT ");
		StringBuffer destBuff = new StringBuffer("INSERT INTO ")
			.append(destTab)
			.append(" (");
		
		for (int i = 0; i < destColList.size(); ++i)
		{
			if (0 < i)
			{
				srcBuff.append(",");
				destBuff.append(",");
			}
			srcBuff.append(destColList.get(i));
			destBuff.append(destColList.get(i));
		}
		
		srcBuff.append(" FROM ").append(srcTab);
		
		destBuff.append(") VALUES (");
		for (int i = 0; i < destColList.size(); ++i)
		{
			if (0 < i)
				destBuff.append(",?");
			else
				destBuff.append("?");
		}
		destBuff.append(")");
		
		Statement srcSt = srcConn.createStatement();
		ResultSet src = srcSt.executeQuery(srcBuff.toString());
		PreparedStatement dest = destConn.prepareStatement(destBuff.toString());
		
		int count = 0;
		int buffCount = 0;
		while(src.next())
		{
			for (int i = 0; i < destColList.size(); ++i)
			{
				dest.setObject(i + 1, src.getObject(i + 1));
			}
			dest.addBatch();
			
			if (++buffCount == buffSize)
			{
				dest.executeBatch();
				buffCount = 0;
			}
			
			++count;
		}
		
		if (0 < buffCount)
			dest.executeBatch();
		
		return count;
	}
	
	public static List getTableColumns(Connection conn, String tab)
		throws Exception
	{
		DatabaseMetaData dmd = conn.getMetaData();
		ResultSet destCol = dmd.getColumns(null, null, tab, null);
		List r = new ArrayList();
		while(destCol.next())
		{
			r.add(destCol.getString("COLUMN_NAME"));
		}
		
		return r;
	}
}
